#!/usr/bin/env python3
"""
Java BUG检测智能体
专门针对Java代码进行BUG检测和修复建议
支持OpenAI GPT和Kimi K2模型
"""

import click
import sys
from pathlib import Path
from colorama import init, Fore, Style
from java_scanner import JavaFileScanner
from java_bug_detector import JavaBugDetector
from bug_report_generator import JavaBugReportGenerator

# 初始化colorama
init()

def print_banner():
    """打印程序横幅"""
    banner = f"""
{Fore.RED}
╔══════════════════════════════════════════════════════════════╗
║                    🐛 Java BUG检测智能体                      ║
║                  Java Bug Detection AI Agent                ║
║                                                              ║
║           专注于Java代码的BUG检测和修复建议                    ║
║              支持 OpenAI GPT 和 Kimi K2 模型                 ║
╚══════════════════════════════════════════════════════════════╝
{Style.RESET_ALL}
"""
    print(banner)

def progress_callback(current: int, total: int, file_path: str):
    """进度回调函数"""
    percentage = (current / total) * 100
    bar_length = 50
    filled_length = int(bar_length * current // total)
    bar = '█' * filled_length + '-' * (bar_length - filled_length)
    
    print(f'\r{Fore.GREEN}检测进度: |{bar}| {percentage:.1f}% ({current}/{total}) '
          f'{Fore.YELLOW}正在分析: {file_path[:45]}...{Style.RESET_ALL}', end='')

@click.command()
@click.option('--path', '-p', default='.', help='Java项目路径 (默认: 当前目录)')
@click.option('--output', '-o', default='java_bug_reports', help='报告输出目录 (默认: java_bug_reports)')
@click.option('--max-files', '-m', default=30, help='最大检测文件数 (默认: 30)')
@click.option('--severity', '-s', 
              type=click.Choice(['all', 'high', 'medium']), 
              default='all', 
              help='只显示指定严重程度的BUG (默认: all)')
@click.option('--dry-run', is_flag=True, help='只扫描Java文件，不进行实际BUG检测')
@click.option('--quick-only', is_flag=True, help='只进行快速预扫描，不使用AI分析')
@click.option('--test-connection', is_flag=True, help='测试AI服务连接')
def main(path, output, max_files, severity, dry_run, quick_only, test_connection):
    """Java BUG检测智能体 - 专门检测Java代码中的BUG并提供修复建议"""
    
    print_banner()
    
    # 测试连接模式
    if test_connection:
        print(f"{Fore.YELLOW}🔧 正在测试AI服务连接...{Style.RESET_ALL}")
        try:
            detector = JavaBugDetector()
            test_result = detector.test_connection()
            
            if test_result['status'] == 'success':
                print(f"{Fore.GREEN}✅ 连接测试成功!{Style.RESET_ALL}")
                print(f"  • AI提供商: {test_result['provider'].upper()}")
                print(f"  • 使用模型: {test_result['model']}")
                print(f"  • 响应内容: {test_result['response']}")
                print(f"  • Token消耗: {test_result['tokens_used']}")
            else:
                print(f"{Fore.RED}❌ 连接测试失败!{Style.RESET_ALL}")
                print(f"  • AI提供商: {test_result['provider'].upper()}")
                print(f"  • 使用模型: {test_result['model']}")
                print(f"  • 错误信息: {test_result['error']}")
                sys.exit(1)
        except Exception as e:
            print(f"{Fore.RED}❌ 连接测试异常: {e}{Style.RESET_ALL}")
            sys.exit(1)
        return
    
    # 验证项目路径
    project_path = Path(path).resolve()
    if not project_path.exists():
        print(f"{Fore.RED}❌ 错误: 项目路径不存在: {project_path}{Style.RESET_ALL}")
        sys.exit(1)
    
    print(f"{Fore.BLUE}📂 Java项目路径: {project_path}{Style.RESET_ALL}")
    print(f"{Fore.BLUE}📁 报告输出目录: {output}{Style.RESET_ALL}")
    print(f"{Fore.BLUE}🎯 严重程度过滤: {severity}{Style.RESET_ALL}")
    
    # 显示AI配置信息
    try:
        from config import JavaBugDetectorConfig
        config = JavaBugDetectorConfig()
        provider = config.get_current_provider()
        if provider == 'openai':
            model = config.OPENAI_MODEL
        elif provider == 'kimi':
            model = config.KIMI_MODEL
        else:
            model = 'unknown'
        
        print(f"{Fore.CYAN}🤖 AI配置: {provider.upper()} - {model}{Style.RESET_ALL}")
    except Exception as e:
        print(f"{Fore.YELLOW}⚠️  无法获取AI配置信息: {e}{Style.RESET_ALL}")
    
    print()
    
    try:
        # 1. 扫描Java文件
        print(f"{Fore.YELLOW}🔍 正在扫描Java文件...{Style.RESET_ALL}")
        scanner = JavaFileScanner(str(project_path))
        java_files = scanner.scan_java_files()
        
        if not java_files:
            print(f"{Fore.RED}❌ 没有找到Java文件 (.java){Style.RESET_ALL}")
            sys.exit(1)
        
        # 限制文件数量
        if len(java_files) > max_files:
            print(f"{Fore.YELLOW}⚠️  找到 {len(java_files)} 个Java文件，限制为前 {max_files} 个{Style.RESET_ALL}")
            java_files = java_files[:max_files]
        
        print(f"{Fore.GREEN}✅ 找到 {len(java_files)} 个Java文件{Style.RESET_ALL}")
        
        # 显示包分布
        packages = {}
        for file_info in java_files:
            pkg = file_info['package']
            packages[pkg] = packages.get(pkg, 0) + 1
        
        print(f"\n{Fore.CYAN}📦 包分布:{Style.RESET_ALL}")
        for pkg, count in sorted(packages.items()):
            print(f"  • {pkg}: {count} 个文件")
        
        if dry_run:
            print(f"\n{Fore.YELLOW}🔍 试运行模式 - 只显示扫描结果{Style.RESET_ALL}")
            for file_info in java_files:
                print(f"  📄 {file_info['relative_path']} "
                      f"(包: {file_info['package']}, {file_info['size']} bytes)")
            return
        
        # 2. 读取文件内容并进行快速预扫描
        print(f"\n{Fore.YELLOW}📖 正在读取文件内容并进行预扫描...{Style.RESET_ALL}")
        files_data = []
        total_quick_issues = {}
        
        for file_info in java_files:
            try:
                content = scanner.get_file_content(file_info['path'])
                quick_scan_results = scanner.quick_bug_scan(content)
                files_data.append((file_info, content, quick_scan_results))
                
                # 统计预扫描结果
                for issue, count in quick_scan_results.items():
                    total_quick_issues[issue] = total_quick_issues.get(issue, 0) + count
                
            except Exception as e:
                print(f"{Fore.RED}❌ 读取文件失败 {file_info['relative_path']}: {e}{Style.RESET_ALL}")
        
        if not files_data:
            print(f"{Fore.RED}❌ 没有成功读取任何文件内容{Style.RESET_ALL}")
            sys.exit(1)
        
        print(f"{Fore.GREEN}✅ 成功读取 {len(files_data)} 个Java文件{Style.RESET_ALL}")
        
        # 显示预扫描统计
        if total_quick_issues:
            print(f"\n{Fore.CYAN}🔍 预扫描发现的潜在问题:{Style.RESET_ALL}")
            for issue, count in sorted(total_quick_issues.items(), key=lambda x: x[1], reverse=True):
                print(f"  • {issue}: {count} 处")
        
        if quick_only:
            print(f"\n{Fore.YELLOW}⚡ 快速扫描模式 - 只进行预扫描分析{Style.RESET_ALL}")
            # 这里可以生成一个简单的预扫描报告
            return
        
        # 3. AI BUG检测
        print(f"\n{Fore.YELLOW}🤖 开始AI BUG检测分析...{Style.RESET_ALL}")
        detector = JavaBugDetector()
        
        # 显示使用的AI模型
        provider = detector.provider
        model = detector._get_model_name()
        print(f"{Fore.CYAN}使用模型: {provider.upper()} - {model}{Style.RESET_ALL}")
        
        print()  # 为进度条留出空间
        bug_results = detector.batch_detect(files_data, progress_callback)
        print()  # 进度条结束后换行
        
        # 统计结果
        successful = len([r for r in bug_results if r['status'] == 'success'])
        failed = len([r for r in bug_results if r['status'] == 'error'])
        total_tokens = sum(r['tokens_used'] for r in bug_results)
        
        # 按严重程度统计
        high_risk = len([r for r in bug_results if r.get('severity_level') == 'high'])
        medium_risk = len([r for r in bug_results if r.get('severity_level') == 'medium'])
        low_risk = len([r for r in bug_results if r.get('severity_level') == 'low'])
        
        print(f"\n{Fore.GREEN}✅ BUG检测完成!{Style.RESET_ALL}")
        print(f"  • 成功检测: {successful} 个文件")
        print(f"  • 检测失败: {failed} 个文件")
        print(f"  • 🔴 高风险: {high_risk} 个文件")
        print(f"  • 🟡 中风险: {medium_risk} 个文件")
        print(f"  • 🟢 低风险: {low_risk} 个文件")
        print(f"  • 总Token消耗: {total_tokens:,}")
        print(f"  • 使用模型: {provider.upper()} - {model}")
        
        # 4. 生成报告
        print(f"\n{Fore.YELLOW}📝 正在生成BUG检测报告...{Style.RESET_ALL}")
        report_generator = JavaBugReportGenerator(output)
        
        # 根据严重程度过滤结果
        if severity != 'all':
            filtered_results = [r for r in bug_results if r.get('severity_level') == severity]
            if not filtered_results:
                print(f"{Fore.YELLOW}⚠️  没有找到 {severity} 严重程度的BUG{Style.RESET_ALL}")
            bug_results = filtered_results
        
        html_report = report_generator.generate_html_report(bug_results, str(project_path))
        summary_report = report_generator.generate_summary_report(bug_results, str(project_path))
        
        print(f"\n{Fore.GREEN}🎉 报告生成完成!{Style.RESET_ALL}")
        print(f"  • 📄 详细HTML报告: {html_report}")
        print(f"  • 📋 摘要报告: {summary_report}")
        
        # 给出修复建议
        if high_risk > 0:
            print(f"\n{Fore.RED}🚨 发现 {high_risk} 个高风险文件，建议立即修复！{Style.RESET_ALL}")
        elif medium_risk > 0:
            print(f"\n{Fore.YELLOW}⚠️  发现 {medium_risk} 个中风险文件，建议优先处理{Style.RESET_ALL}")
        else:
            print(f"\n{Fore.GREEN}✨ 很好！没有发现高风险BUG{Style.RESET_ALL}")
        
        if failed > 0:
            print(f"\n{Fore.YELLOW}⚠️  有 {failed} 个文件检测失败，请检查API配置和网络连接{Style.RESET_ALL}")
        
    except KeyboardInterrupt:
        print(f"\n\n{Fore.YELLOW}⚠️  用户中断操作{Style.RESET_ALL}")
        sys.exit(1)
    except Exception as e:
        print(f"\n{Fore.RED}❌ 程序执行出错: {e}{Style.RESET_ALL}")
        import traceback
        traceback.print_exc()
        sys.exit(1)

if __name__ == '__main__':
    main()
